import React, { useState, useRef, createContext, useContext } from 'react';
import { Table } from 'antd';
import { Resizable } from 'react-resizable';
import type { ResizeCallbackData } from 'react-resizable';
import 'react-resizable/css/styles.css';
import type { DragEndEvent, DragOverEvent, UniqueIdentifier } from '@dnd-kit/core';
import { closestCenter, DndContext, DragOverlay, PointerSensor, useSensor, useSensors } from '@dnd-kit/core';
import { restrictToHorizontalAxis } from '@dnd-kit/modifiers';
import { arrayMove, horizontalListSortingStrategy, SortableContext, useSortable } from '@dnd-kit/sortable';

// 添加拖拽状态上下文
interface DragIndexState {
  active: UniqueIdentifier;
  over: UniqueIdentifier | undefined;
  direction?: 'left' | 'right';
}

const DragIndexContext = createContext<DragIndexState>({ active: -1, over: -1 });

// 添加拖拽样式函数
const dragActiveStyle = (dragState: DragIndexState, id: string) => {
  const { active, over, direction } = dragState;
  let style: React.CSSProperties = {};
  if (active && active === id) {
    style = { backgroundColor: '#1890ff', opacity: 0 };
  } else if (over && id === over && active !== over) {
    style = direction === 'right' ? { borderRight: '2px dashed #1890ff' } : { borderLeft: '2px dashed #1890ff' };
  }
  return style;
};

// 修改 ResizableTitleProps 接口
interface ResizableTitleProps {
  onResize: (e: React.SyntheticEvent, data: ResizeCallbackData) => void;
  width?: number;
  id?: string;
  [key: string]: any;
}

const ResizableTitle: React.FC<ResizableTitleProps> = (props) => {
  const { onResize, width, ...restProps } = props;
  const [isResizing, setIsResizing] = useState(false);
  const dragState = useContext(DragIndexContext);
  const { attributes, listeners, setNodeRef, isDragging } = useSortable({ id: restProps.id as string });
  const startEvent = useRef<{ clientX: number } | null>(null);
  const startWidth = useRef(0);

  interface EventProps {
    onClick?: (e: React.SyntheticEvent) => void;
  }

  const eventProps: EventProps = {};
  if (isResizing) {
    eventProps.onClick = (e: React.SyntheticEvent) => {
      console.log(e);
    };
  }

  if (!width) {
    return <th {...restProps} />;
  }

  const style: React.CSSProperties = {
    ...restProps.style,
    position: 'relative',
    ...(isDragging ? { position: 'relative', zIndex: 100, userSelect: 'none' } : {}),
    ...dragActiveStyle(dragState, restProps.id as string)
  };

  return (
    <Resizable
      width={width}
      height={0}
      minConstraints={[70, 0]}
      handle={
        <span
          className="react-resizable-handle"
          style={{
            position: 'absolute',
            right: 0,
            top: 0,
            bottom: 0,
            width: '10px',
            cursor: 'col-resize',
            zIndex: 1
          }}
          onClick={(e: React.SyntheticEvent) => {
            e.stopPropagation();
            e.preventDefault();
          }}
          onMouseDown={(e: React.SyntheticEvent) => {
            setIsResizing(true);
            e.preventDefault();
            e.stopPropagation();
          }}
        />
      }
      onResize={(e, data) => {
        if (startEvent.current && startWidth.current) {
          const mouseEvent = e as unknown as MouseEvent;
          onResize(e, { ...data, size: { width: Math.max(mouseEvent.clientX - startEvent.current.clientX + startWidth.current, 70), height: 0 } });
        } else {
          onResize(e, data);
        }
      }}
      onResizeStart={(e: React.SyntheticEvent) => {
        const mouseEvent = e as unknown as MouseEvent;
        startEvent.current = { clientX: mouseEvent.clientX };
        startWidth.current = width;
        e.preventDefault();
        setIsResizing(true);
      }}
      onResizeStop={() => {
        startEvent.current = null;
        startWidth.current = 0;
        setTimeout(() => {
          setIsResizing(false);
        }, 100);
      }}
      draggableOpts={{ enableUserSelectHack: false }}>
      <th
        {...restProps}
        {...eventProps}
        ref={setNodeRef}
        style={style}
        onMouseDown={() => {
          
        }}>
        {restProps.children}
        <div
          style={{
            position: 'absolute',
            left: 0,
            top: 0,
            right: '10px',
            bottom: 0,
            cursor: 'move',
            zIndex: 1000
          }}
          {...attributes}
          {...listeners}
        />
      </th>
    </Resizable>
  );
};

interface DraggableTableProps {
  columns: any[];
  onColumnsChange: (columns: any[]) => void;
  [key: string]: any;
}

const DraggableTable: React.FC<DraggableTableProps> = (props) => {
  const { columns, onColumnsChange, ...restProps } = props;
  const [dragIndex, setDragIndex] = useState<DragIndexState>({ active: -1, over: -1 });

  // 修改 handleResize 函数
  const handleResize =
    (id: string) =>
    (e: React.SyntheticEvent, { size }: ResizeCallbackData) => {
      onColumnsChange(
        columns.map((col) => {
          if (col.key === id) {
            return {
              ...col,
              width: size.width,
              onHeaderCell: () =>
                ({
                  width: size.width,
                  onResize: handleResize(id),
                  id: col.key
                }) as any
            };
          }
          return col;
        })
      );
    };

  columns.forEach((column) => {
    column.onHeaderCell = () =>
      ({
        width: column.width,
        onResize: handleResize(column.dataIndex),
        id: column.dataIndex
      }) as any;
  });

  // 添加拖拽传感器
  const sensors = useSensors(
    useSensor(PointerSensor, {
      activationConstraint: {
        distance: 1
      }
    })
  );

  // 修改拖拽结束处理函数
  const onDragEnd = ({ active, over }: DragEndEvent) => {
    if (active.id !== over?.id) {
      const activeIndex = columns.findIndex((i) => i.key === active?.id);
      const overIndex = columns.findIndex((i) => i.key === over?.id);
      onColumnsChange(arrayMove(columns, activeIndex, overIndex));
    }
    setDragIndex({ active: -1, over: -1 });
  };

  // 修改拖拽过程处理函数
  const onDragOver = ({ active, over }: DragOverEvent) => {
    if (!columns) return;
    const activeIndex = columns.findIndex((i) => i.key === active.id);
    const overIndex = columns.findIndex((i) => i.key === over?.id);
    setDragIndex({
      active: active.id,
      over: over?.id,
      direction: overIndex > activeIndex ? 'right' : 'left'
    });
  };

  return (
    <DndContext
      sensors={sensors}
      modifiers={[restrictToHorizontalAxis]}
      onDragEnd={onDragEnd}
      onDragOver={onDragOver}
      collisionDetection={closestCenter}>
      {columns && (
        <SortableContext items={columns.map((i) => i.key as string)} strategy={horizontalListSortingStrategy}>
          <DragIndexContext.Provider value={dragIndex}>
            <Table
              {...restProps}
              columns={columns}
              components={{
                header: {
                  cell: ResizableTitle
                }
              }}
            />
          </DragIndexContext.Provider>
        </SortableContext>
      )}
      <DragOverlay>
        {columns && (
          <div
            style={{
              backgroundColor: '#e3f0ff',
              padding: '4.5px 8px 5px 8px',
              // borderTop: '1px solid #e3f0ff',
              fontSize: 14,
              fontWeight: 'bold',
              opacity: 0.8,
              zIndex: 1000
            }}>
            {columns[columns.findIndex((i) => i.key === dragIndex.active)]?.title as React.ReactNode}
          </div>
        )}
      </DragOverlay>
    </DndContext>
  );
};

export default DraggableTable;
